<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CIHeadStart Development Tools Helpers
 *
 * @author Casey McLaughlin
 * @package CIHeadStart
 * @link http://code.google.com/p/ciheadstart
 */

// --------------------------------------------------------------------

/**
 * Returns the current site mode (development, testing, demo, or production).
 *
 * If this function cannot find the site mode in the $site_config, it assumes
 * production (which is the safest site mode)
 *
 * @global object $site_config
 * @return string
 */
function get_site_mode()
{
	global $site_config;
	
	if (isset($site_config) && is_object($site_config))
		return $site_config->site_mode;
	else //assume production if no site mode is found (for security)
		return 'production';
}

// --------------------------------------------------------------------

/**
 * Checks to see if the current site mode matches the parameter $which
 *
 * @param string $which
 * @return boolean
 */
function is_mode($which)
{
	if ($which == get_site_mode())
		return TRUE;
	else
		return FALSE;
}

// --------------------------------------------------------------------

/**
 * Prints the HTML for the development tools
 * sidebar on the page.
 *
 * Returns VOID if everything went well; FALSE if there was a problem
 *
 * @global object $site_config
 * @return void
 */
function show_development_tools()
{
	global $site_config;

	//Check to make sure that the site is in development mode and that devtools are enabled
	if ( ! isset($site_config->enable_devtools) OR $site_config->enable_devtools !== TRUE)
		return FALSE;		
	if ( ! is_mode('development'))
		return FALSE;

	//Load CI
	$ci =& get_instance();

	//The ALL Good Flag is TRUE unless we find any problems...
	$all_good = TRUE;

	//
	//Perform program integrity checks
	//

	//If dbsync file exists, then check sync status
	$ci->load->library('dbsync');
	if ($ci->dbsync->check_schema_exists())
	{
		$db_sync_diffs = $ci->dbsync->get_db_schema_changes();
		$db_sync_num_diffs = $ci->dbsync->get_total_number_of_differences();

		if ($ci->input->post('db_sync_form_submitted'))
		{
			if (isset($_POST['run_changes']) && is_array($_POST['run_changes']) && count($_POST['run_changes']) > 0)
			{
				//Derive the items to skip, which is what we will send the library
				$items_to_change = array_keys($_POST['run_changes']);
				$items_to_skip = array_diff(array_keys($db_sync_diffs), $items_to_change);
				$db_sync_diffs = $ci->dbsync->sync_db_and_file(NULL, $items_to_skip);

				if ($ci->dbsync->get_last_sync_result() === TRUE)
					$db_sync_result = "Succesfully synced the database and the schema file!";
				else
					$db_sync_result = "Synced the database and the schema file, but there were some errors.  See below.";
			}
			else
				$db_sync_result = "You did not select any items to change in the database.";

			$db_sync_num_diffs = $ci->dbsync->get_total_number_of_differences();
		}

		if ($db_sync_num_diffs == 0)
			$db_sync_needed = FALSE;
		else
		{
			$db_sync_needed = TRUE;
			$all_good = FALSE;
		}
	}

	?>
	<div id='develop_tools'>

		<div id="develop_tools_db_contents">
			<p><strong>Database Synchronization</strong></p>

			<p id="develop_tools_num_db_diffs">Number of changes between database and file: <strong><?php echo $db_sync_num_diffs;?></strong></p>

			<?php if (isset($db_sync_result)): ?>
				<p id="develop_tools_db_sync_result"><?php echo $db_sync_result; ?></p>
			<?php endif; ?>

			<?php if ($db_sync_num_diffs > 0 OR isset($db_sync_result)): ?>
				<form id="develop_tools_db_form" action="<?php echo current_url(); ?>" method="post">
				<p style="display: none;"><input type="hidden" name="db_sync_form_submitted" value="true" /></p>
				<ul id="develop_tools_db_sync_changes">
					<?php foreach($db_sync_diffs as $idnum => $schema_change): ?>
					<li>
						<?php if ( ! isset($schema_change->action_result) OR ! begins_with($schema_change->action_result, 'success')): ?>
							<input type="checkbox" name="run_changes[<?php echo $idnum; ?>]" id="run_changes_<?php echo $idnum; ?>"/> <label for="run_changes_<?php echo $idnum; ?>">Change number: <?php echo $idnum;?></label>
						<?php else: ?>
							<span class="db_sync_changes_name">Change number: <?php echo $idnum;?></span>
						<?php endif; ?>
						<ul>

							<li class="db_sync_changes_explanation"><?php echo $schema_change->explanation; ?></li>
							<li class="db_sync_changes_action"><?php echo $schema_change->change_action; ?></li>
							<li class="db_sync_changes_sql"><?php echo $schema_change->sql_query; ?></li>

							<?php if (isset($schema_change->action_result)): ?>
								<?php if (isset($schema_change->action_succeeded) && $schema_change->action_succeeded == TRUE): ?>
									<li class="db_sync_changes_result_succeeded">Result: <strong><?php echo $schema_change->action_result; ?></strong></li>
								<?php else: ?>
									<li class="db_sync_changes_result">Result: <strong><?php echo $schema_change->action_result; ?></strong></li>
								<?php endif; ?>
							<?php endif; ?>

						</ul>
					</li>
					<?php endforeach; ?>
				</ul>

				<p><button type="submit">Submit Changes &raquo;</button></p>

				</form>
			<?php else: ?>
				<p>Hooray! There are no pending changes to the database.</p>
			<?php endif; ?>
		</div>

		<div id='develop_tools_contents'>
			<p><strong>Development Tools</strong></p>
			<p><a id='enable_blueprint_grid' href='#'>Toggle Blueprint Grid</a></p>
			<p><a id='validate_html' href='http://validator.w3.org/check?uri=<?php echo current_url();?>' title='Validate CSS for this page'>Validate HTML</a></p>
			<p><a id='validate_css' href='http://jigsaw.w3.org/css-validator/validator?uri=<?php echo current_url();?>' title="Validate CSS for this page">Validate CSS</a></p>
			<p>Load time: <strong>{elapsed_time} s</strong></p>
			<p>Mem usage: <strong>{memory_usage}</strong></p>
			<hr />
			<p>Blueprint Columns: <strong>24</strong></p>
			<p>CI Version: <strong><?php echo CI_VERSION;?></strong></p>
			<p>PHP Version: <strong><?php echo phpversion();?></strong></p>
			<?php if (is_numeric(return_svn_revision())): ?>
				<p>SVN Revision: <strong><?php echo return_svn_revision();?></strong></p>
			<?php endif; ?>
			<?php if (return_version_from_svn() !== FALSE): ?>
				<p>Version: <strong><?php echo return_version_from_svn();?></strong></p>
			<?php endif; ?>

			<hr />
			<p>Session Timeout: <strong><?php echo $ci->config->item('sess_expiration') / 60; ?> min</strong></p>
			<p>Cookie Size: <strong><?php echo number_format((str_bytes(implode('', $_COOKIE)) / 1024), 2); ?> kb</strong> of 4kb</p>

			<?php if (isset($db_sync_needed)): ?>
				<hr />
				<?php if (isset($db_sync_result)): ?>
					<p id="db_sync_result"><a href='#' title="Show database sync information">Database synced!<br />Click to see results.</a></p>
				<?php elseif ($db_sync_needed): ?>
					<p id='db_sync_bad'><a href='#' title='Show database sync information'>Database out of sync! (see diffs)</a></p>
				<?php else: ?>
					<p id='db_sync_good'><a href='#' title='Show database sync information'>Database in sync</a></p>
				<?php endif; ?>
			<?php endif; ?>
		</div>

		<div id='develop_tools_toggle'>
			<?php if ($all_good): ?>
				<img src="<?php echo base_url(); ?>assets/development/develop_green_dot.png" alt="good" />
			<?php else: ?>
				<img src="<?php echo base_url(); ?>assets/development/develop_red_dot.png" alt="bad" />
			<?php endif; ?>
		</div>
	</div>
	<?php

}

// --------------------------------------------------------------------

/**
 * If php_shell_exec is not disabled in the php.ini file, and
 * SVN is in the system path, this function returns the current SVN
 * revision.
 *
 * If SVN is not available, or shell_exec is disabled, this function will
 * return FALSE.
 *
 * @return int
 */
function return_svn_revision()
{
	$abs_path = realpath(BASEPATH . '..');
		
	$result = `svn info "$abs_path"`;
	if (strpos($result, "Revision:"))
	{
		$result = explode("\n", $result);
		foreach($result as $line)
		{
			if (begins_with($line, "Revision:"))
			{
				list($revword, $num) = explode(':', $line);
				return trim($num);
			}
		}
	}
	
	//if made it here
	return FALSE;
}

// --------------------------------------------------------------------

/**
 * If php_shell_exec is not disabled in the php.ini file, and
 * SVN is in the system path, this function returns the name of the
 * branch or tag of the current working copy of this application.
 *
 * If SVN is not available, or shell_exec is disabled, this function will
 * return FALSE.
 *
 * @return int
 */
function return_version_from_svn()
{	
	$result = `svn info`;
	if (strpos($result, "URL:") !== FALSE && strpos($result, "Repository Root:") !== FALSE)
	{			
		$url = NULL;
		$root = NULL;
		$loc;
		
		$result = explode("\n", $result);
		foreach ($result as $line)
		{
			if (begins_with($line, "URL:"))
			{
				list($word, $url) = explode(':', $line, 2);
				$url = trim($url);
			}
			elseif (begins_with($line, "Repository Root:"))
			{
				list($word, $root) = explode(':', $line, 2);
				$root = trim($root);
			}
		}
					
		if ($url !== NULL && $root !== NULL)
		{
			if (begins_with($url, $root))
			{
				$loc = substr($url, strlen($root));
				$loc_segments = array_trim(explode("/", $loc));
				
				if ($loc_segments[0] == 'tags')
					return $loc_segments[1];
				elseif ($loc_segments[0] == 'branches')
					return "Branch: " . $loc_segments[1];
				else //if ($loc_segments[0] == 'trunk')
					return "Dev (trunk)";
			}	 
		}
	}
	
	//if made it here
	return FALSE;
}

// --------------------------------------------------------------------

/**
 * Produce debug messages
 *
 * This is a more robust alternative to var_dump() or print_r().  It also
 * integrates with firephp and provides logging
 *
 * Configure the functionality for this funciton in the $site_config object.
 *
 * @global object $site_config
 * @param mixed $item
 * @return void
 */
function debug($item)
{
	//Don't run debug functions
	//ever in production mode
	if (is_mode('production'))
		return FALSE;
	
	global $site_config;
	
	if ($site_config->debug_tool == 'off')
		return;
		
	if (strpos($site_config->debug_tool, "|") !== FALSE)
		$debug_tools = explode("|", strtolower($site_config->debug_tool));
	else
		$debug_tools = array(strtolower($site_config->debug_tool));
		
	$item = print_r($item, TRUE);		
		
	foreach($debug_tools as $tool)
	{
		if ($tool == 'onscreen')
		{
			echo "<pre class='debug'>$item</pre>";
		}
		elseif ($tool == 'firephp')
		{
			if ( ! @include(APPPATH . '/plugins/firephp/firephp.php'))
				throw new Exception("Could not load the FirePHP library!");	

			fb($item);
		}
		elseif (begins_with($tool, 'logfile'))
		{
			if (strpos($tool, ":"))
			{
				list($log, $file_loc) = explode(":", $tool);
				
				if (is_writable($file_loc))
					file_put_contents($file, "\n[".time()."] " . $item, FILE_APPEND | LOCK_EX);
				else
					throw new Exception("Cannot write debug to logfile; file not existent or not writable");
			}
		}
	}
}

/* End of file develop_helper.php */
/* Location: ./app/helpers/develop_helper.php */